package api

import (
	"context"
	"fmt"
	"github.com/gin-gonic/gin"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
	"net/http"
	"project07_resume_web/src/form"
	"project07_resume_web/src/global"
	"project07_resume_web/src/global/response"
	models "project07_resume_web/src/model"
	"project07_resume_web/src/proto/resume_proto"
	"project07_resume_web/src/utils"
	"strconv"
	"strings"
)

func SwitchGrpcErrorToHttp(err error, c *gin.Context) {
	if err != nil {
		if e, ok := status.FromError(err); ok {
			switch e.Code() {
			case codes.NotFound:
				c.JSON(http.StatusNotFound, gin.H{
					"msg": e.Message(),
				})
			case codes.Internal:
				c.JSON(http.StatusInternalServerError, gin.H{
					"msg": "内部错误",
				})
			case codes.InvalidArgument:
				c.JSON(http.StatusBadRequest, gin.H{
					"msg": "参数错误",
				})
			case codes.AlreadyExists:
				c.JSON(http.StatusBadRequest, gin.H{
					"msg": "用户已存在",
				})
			default:
				c.JSON(http.StatusInternalServerError, gin.H{
					"msg": "未知错误",
				})
			}
		}
	}
}

//router.GET("/getresumlist")
//router.GET("/getresumebyid")
//router.GET("/getresumebyhouseid")
//router.GET("/getresumebyresumename")
//router.POST("/createresume")
//router.PUT("/updateresume")
//router.DELETE("/deleteresumebyresumeid")

func DeleteResumeByResumeId(c *gin.Context) {
	ResumeIds := c.Param("resumeid")
	ResumeId, err := strconv.Atoi(ResumeIds)
	if err != nil {
		SwitchGrpcErrorToHttp(err, c)
		return
	}
	_, err = global.ResumeClient.DeleteResumeByResumeId(context.Background(), &resume_proto.ResumeId{Id: int32(ResumeId)})
	if err != nil {
		SwitchGrpcErrorToHttp(err, c)
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"msg":  "删除成功",
		"data": nil,
		"code": 200,
	})
}

func UpdateResume(c *gin.Context) {
	var resume form.ResumeRes
	userIds := c.Param("userid")
	resumeIds := c.Param("resumeid")
	resumeId, err := strconv.Atoi(resumeIds)
	if err != nil {
		SwitchGrpcErrorToHttp(err, c)
		return
	}
	userId, err := strconv.Atoi(userIds)
	if err != nil {
		SwitchGrpcErrorToHttp(err, c)
		return
	}
	err = c.ShouldBind(&resume)
	if err != nil {
		utils.ErrResp(err)
		return
	}

	_, err = global.ResumeClient.UpdateResume(context.Background(), &resume_proto.UpdateResumeReq{
		UserId:   int32(userId),
		ResumeId: int32(resumeId),
		Name:     resume.Name,
		Age:      int32(resume.Age),
		Sex:      resume.Sex,
		WorkExp:  resume.WorkExp,
		Describe: resume.Describe,
		Reword:   int32(resume.Reword),
	})
	if err != nil {
		SwitchGrpcErrorToHttp(err, c)
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"msg":  "创建成功",
		"data": nil,
		"code": 200,
	})
}

func CreateResume(c *gin.Context) {
	var resume form.ResumeRes
	err := c.ShouldBind(&resume)
	if err != nil {
		utils.ErrResp(err)
		return
	}

	_, err = global.ResumeClient.CreateResume(context.Background(), &resume_proto.CreateResumeReq{
		Name:           resume.Name,
		Age:            int32(resume.Age),
		Sex:            resume.Sex,
		HouseKeepingId: int32(resume.HouseKeepingId),
		WorkExp:        resume.WorkExp,
		Describe:       resume.Describe,
		Reword:         int32(resume.Reword),
	})
	if err != nil {
		SwitchGrpcErrorToHttp(err, c)
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"msg":  "创建成功",
		"data": nil,
		"code": 200,
	})
}

func GetResumeByResumeName(c *gin.Context) {
	pns := c.Query("pn")
	resumeName := c.Query("resumename")
	pn, err := strconv.Atoi(pns)
	if err != nil {
		SwitchGrpcErrorToHttp(err, c)
		return
	}
	if err != nil {
		SwitchGrpcErrorToHttp(err, c)
		return
	}

	res, err := global.ResumeClient.GetResumeByResumeName(context.Background(), &resume_proto.ResumeName{
		Name: resumeName,
		Page: &resume_proto.PageInfo{
			Pn:    int32(pn),
			PSize: 5,
		},
	})
	if err != nil {
		SwitchGrpcErrorToHttp(err, c)
		return
	}

	result := []response.ResumeRes{}

	for _, v := range res.Res {
		vv := response.ResumeRes{
			Name:           v.Name,
			Age:            int(v.Age),
			HouseKeepingId: int(v.HouseKeepingId),
			WorkExp:        v.WorkExp,
			Describe:       v.Describe,
			Reword:         int(v.Reword),
			Sex:            v.Sex,
		}
		result = append(result, vv)
	}

	c.JSON(http.StatusOK, gin.H{
		"msg":  "查询成功",
		"data": result,
		"code": 200,
	})

	c.JSON(http.StatusOK, gin.H{
		"msg":  "查询成功",
		"data": result,
		"code": 200,
	})
}

func GetResumeByHouseId(c *gin.Context) {
	resumeIds := c.Query("resumeid")
	pns := c.Query("pn")
	pn, err := strconv.Atoi(pns)
	if err != nil {
		SwitchGrpcErrorToHttp(err, c)
		return
	}
	resumeId, err := strconv.Atoi(resumeIds)
	if err != nil {
		SwitchGrpcErrorToHttp(err, c)
		return
	}

	res, err := global.ResumeClient.GetResumeByHouseKeepingId(context.Background(), &resume_proto.HouseKeepingId{
		Page: &resume_proto.PageInfo{
			Pn:    int32(pn),
			PSize: 5,
		},
		Id: int32(resumeId),
	})
	if err != nil {
		SwitchGrpcErrorToHttp(err, c)
		return
	}

	result := []response.ResumeRes{}

	for _, v := range res.Res {
		vv := response.ResumeRes{
			Name:           v.Name,
			Age:            int(v.Age),
			HouseKeepingId: int(v.HouseKeepingId),
			WorkExp:        v.WorkExp,
			Describe:       v.Describe,
			Reword:         int(v.Reword),
		}
		result = append(result, vv)
	}

	c.JSON(http.StatusOK, gin.H{
		"msg":  "查询成功",
		"data": result,
		"code": 200,
	})

	c.JSON(http.StatusOK, gin.H{
		"msg":  "查询成功",
		"data": result,
		"code": 200,
	})
}

func GetResumeByResumeId(c *gin.Context) {
	resumeIds := c.Query("resumeid")
	resumeId, err := strconv.Atoi(resumeIds)
	if err != nil {
		SwitchGrpcErrorToHttp(err, c)
		return
	}

	res, err := global.ResumeClient.GetResumeByResumeId(context.Background(), &resume_proto.ResumeId{Id: int32(resumeId)})
	if err != nil {
		SwitchGrpcErrorToHttp(err, c)
		return
	}

	result := response.ResumeRes{
		Name:           res.Name,
		Age:            int(res.Age),
		HouseKeepingId: int(res.HouseKeepingId),
		WorkExp:        res.WorkExp,
		Describe:       res.Describe,
		Reword:         int(res.Reword),
	}

	c.JSON(http.StatusOK, gin.H{
		"msg":  "查询成功",
		"data": result,
		"code": 200,
	})
}

func GetResumeList(c *gin.Context) {
	pns := c.Query("pn")
	pn, err := strconv.Atoi(pns)
	if err != nil {
		SwitchGrpcErrorToHttp(err, c)
		return
	}

	res, err := global.ResumeClient.GetResumeList(context.Background(), &resume_proto.PageInfo{
		Pn:    int32(pn),
		PSize: 5,
	})
	if err != nil {
		SwitchGrpcErrorToHttp(err, c)
		return
	}

	result := []response.ResumeRes{}

	for _, v := range res.Res {
		vv := response.ResumeRes{
			Name:           v.Name,
			Age:            int(v.Age),
			HouseKeepingId: int(v.HouseKeepingId),
			WorkExp:        v.WorkExp,
			Describe:       v.Describe,
			Reword:         int(v.Reword),
		}
		result = append(result, vv)
	}

	c.JSON(http.StatusOK, gin.H{
		"msg":  "查询成功",
		"data": result,
		"code": 200,
	})
}

func DownloadResume(c *gin.Context) {
	resumeIds := c.Query("resumeid")
	resumeId, err := strconv.Atoi(resumeIds)
	if err != nil {
		SwitchGrpcErrorToHttp(err, c)
		return
	}
	//获取文件路径
	filePath, err := global.ResumeClient.GetResumeFilePath(context.Background(), &resume_proto.ResumeId{Id: int32(resumeId)})
	if err != nil {
		SwitchGrpcErrorToHttp(err, c)
		return
	}

	c.File(filePath.FilePathName)
}

func UploadResume_Test(c *gin.Context) {
	file, err := c.FormFile("file")
	if err != nil {
		c.String(http.StatusBadRequest, fmt.Sprintf("文件上传失败: %s", err.Error()))
		return
	}

	// 保存文件到指定目录，自动生成唯一的文件名
	err = c.SaveUploadedFile(file, "./staticFile/"+file.Filename)
	if err != nil {
		c.String(http.StatusInternalServerError, fmt.Sprintf("保存文件失败: %s", err.Error()))
		return
	}
	c.String(http.StatusOK, "文件上传成功")
}

func UploadResume(c *gin.Context) {
	//获取到文件
	file, err := c.FormFile("file")
	if err != nil {
		SwitchGrpcErrorToHttp(err, c)
		return
	}
	//文件后缀判断 类型判断
	file_name := file.Filename
	file_name_arr := strings.Split(file_name, ".")
	if len(file_name_arr) != 2 || c.ContentType() != "application/pdf" {
		//文件不合法
		c.JSON(http.StatusInternalServerError, gin.H{
			"code": 500,
			"msg":  "文件格式不对,只允许上传pdf,请重新上传!",
			"data": err,
		})
		return
	}
	c.String(http.StatusOK, "文件上传成功")
	maxSize := int64(1024 * 1024 * 2) //只允许文件大小为2M
	if file.Size > maxSize {
		c.String(http.StatusBadRequest, fmt.Sprintf("file size too large, max size is %d bytes", maxSize))
		return
	}
	claims, _ := c.Get("claims")
	current := claims.(*models.CustomClaims)
	userid := current.ID
	//查询当前用户简历数量
	filename, err_jl := global.ResumeClient.GetResumeNum(context.Background(), &resume_proto.UserId{Uid: int32(userid)})
	filenames := filename.String()
	if filenames == "" { //没有写简历
		file_name_hash1, _ := utils.GenerateRandomString(32)
		Separator_hash2, _ := utils.GenerateRandomString(32)
		//将文件上传到服务器上  文件名 filename_hash
		filenames = file_name_arr[0] + "_" + file_name_hash1 + file_name_arr[1]
		err_upload := c.SaveUploadedFile(file, "./staticFile"+filenames)
		if err_upload != nil {
			c.JSON(http.StatusInternalServerError, gin.H{
				"code": 500,
				"msg":  "文件上传失败,系统错误",
				"data": err,
			})
			return
		}
		//利用hash2作为切分符将简历数据储存到db当中
		filenames = file_name + Separator_hash2
		//保存这个数据到路径当中
		_, err_Resume := global.ResumeClient.SavePathName(context.Background(), &resume_proto.PathReq{Pathname: filenames})
		//保存hash
		_, err_Sep := global.ResumeClient.Uploadhash(context.Background(), &resume_proto.Separator{Separator: Separator_hash2})
		if err_Resume != nil || err_Sep != nil {
			c.JSON(http.StatusInternalServerError, gin.H{
				"code": 500,
				"msg":  "文件上传失败,系统错误",
				"data": err,
			})
			return
		}
		c.String(http.StatusOK, "文件上传成功")
	} else { //已经写过简历
		hash1, err_hash := global.ResumeClient.GetFilenamehash(context.Background(), &resume_proto.UserId{Uid: int32(userid)})
		hash2, err_hash2 := utils.GenerateRandomString(32)
		if err_jl != nil || err_hash2 != nil || err_hash != nil {
			c.JSON(http.StatusInternalServerError, gin.H{
				"code": 500,
				"msg":  "系统错误",
				"data": err,
			})
			return
		}
		Hash1 := hash1.String()
		num := len(strings.Split(filenames, Hash1))
		if num > 3 {
			c.JSON(http.StatusInternalServerError, gin.H{
				"code": 500,
				"msg":  "文件数量过多请删除",
				"data": err,
			})
			return
		}
		filenames += file_name_arr[0] + "_" + hash2
		_, err_Resume := global.ResumeClient.SavePathName(context.Background(), &resume_proto.PathReq{Pathname: filenames})
		err = c.SaveUploadedFile(file, "./staticFile"+file.Filename)
		if err != nil || err_Resume != nil {
			c.JSON(http.StatusInternalServerError, gin.H{
				"code": 500,
				"msg":  "文件保存失败",
				"data": err,
			})
			return
		}
		c.String(http.StatusOK, "文件上传成功")
	}

}
